package org.dromara.admin.utils;

import cn.hutool.crypto.SecureUtil;
import cn.hutool.http.HttpRequest;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.databind.node.ObjectNode;
import org.dromara.common.core.domain.R;
import org.dromara.common.core.exception.ServiceException;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.security.MessageDigest;
import java.util.Map;
import java.util.TreeMap;
import java.util.UUID;

public class OcrUtil {

    private static final ObjectMapper MAPPER = new ObjectMapper()
        .configure(SerializationFeature.ORDER_MAP_ENTRIES_BY_KEYS, true);

    /**
     * 调用 OCR 接口
     *
     * @param apiUrl 请求路径
     * @param appId  应用id
     * @param appKey 应用key
     * @param data   data部分的请求参数（Map，内部会自动升序）
     */
    public static JsonNode callOcr(String apiUrl, String appId, String appKey, Map<String, Object> data) {
        try {
            // 时间戳（秒级）
            String time = String.valueOf(System.currentTimeMillis() / 1000);
            // 随机字符串
            String rand = UUID.randomUUID().toString().replace("-", "");

            // 升序处理
            TreeMap<String, Object> sortedData = new TreeMap<>(data);
            String jsonData = MAPPER.writeValueAsString(sortedData);

            // 生成 sign
            String signStr = appId + "#" + jsonData + "#" + time + "#" + appKey + "#" + rand;
            String sign = md5(signStr);

            // 构造请求体
            ObjectNode root = MAPPER.createObjectNode();
            root.put("time", time);
            root.put("nostr", rand);
            root.put("appid", appId);
            root.put("sign", sign);
            root.set("data", MAPPER.valueToTree(sortedData));

            String requestJson = MAPPER.writeValueAsString(root);
            System.out.println("请求体: " + requestJson);
            // 发起请求
            String resp = sendPost(apiUrl, requestJson);
            System.out.println("响应结果: " + resp);

            return MAPPER.readTree(resp);
        } catch (Exception e) {
            throw new ServiceException("OCR请求失败: " + e.getMessage());
        }
    }

    /**
     * 生成 MD5
     */
    private static String md5(String str) throws Exception {
        MessageDigest md = MessageDigest.getInstance("MD5");
        byte[] digest = md.digest(str.getBytes("UTF-8"));
        StringBuilder sb = new StringBuilder();
        for (byte b : digest) {
            sb.append(String.format("%02x", b & 0xff));
        }
        return sb.toString();
    }

    /**
     * 发送 POST 请求
     */
    private static String sendPost(String urlStr, String jsonBody) throws Exception {
        URL url = new URL(urlStr);
        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
        conn.setRequestMethod("POST");
        conn.setRequestProperty("Content-Type", "application/json;charset=UTF-8");
        conn.setDoOutput(true);

        try (OutputStream os = conn.getOutputStream()) {
            os.write(jsonBody.getBytes("UTF-8"));
        }

        int code = conn.getResponseCode();
        InputStream is = code == 200 ? conn.getInputStream() : conn.getErrorStream();

        try (BufferedReader br = new BufferedReader(new InputStreamReader(is, "UTF-8"))) {
            StringBuilder resp = new StringBuilder();
            String line;
            while ((line = br.readLine()) != null) {
                resp.append(line);
            }
            return resp.toString();
        }
    }
}
